/*
 * @Author: LVGRAPE
 * @LastEditors: LVGRAPE
 */
#include "drv_pwm.h"


tmr_output_config_type tmr_oc_init_structure;

int16_t motor_values[4];

void pwm_init(void)
{
    tmr_output_config_type tmr_oc_init_structure;
    gpio_init_type gpio_init_struct;
    // crm_periph_clock_enable(CRM_IOMUX_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_TMR8_PERIPH_CLOCK, TRUE);

    gpio_default_para_init(&gpio_init_struct);
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_pins = GPIO_PINS_6 | GPIO_PINS_7;
    gpio_init(GPIOA, &gpio_init_struct);
    gpio_init_struct.gpio_pins = GPIO_PINS_0 | GPIO_PINS_1;
    gpio_init(GPIOB, &gpio_init_struct);
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init_struct.gpio_pins = GPIO_PINS_6 | GPIO_PINS_7 | GPIO_PINS_8 | GPIO_PINS_9;
    gpio_init(GPIOC, &gpio_init_struct);

    tmr_base_init(TMR3, 1000, 9);
    tmr_cnt_dir_set(TMR3, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR3, TMR_CLOCK_DIV1);

    tmr_base_init(TMR8, 1000, 9);
    tmr_cnt_dir_set(TMR8, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR8, TMR_CLOCK_DIV1);

    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
    tmr_oc_init_structure.oc_idle_state = FALSE;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
    tmr_oc_init_structure.oc_output_state = TRUE;

    tmr_output_channel_config(TMR8, TMR_SELECT_CHANNEL_1, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR8, TMR_SELECT_CHANNEL_1, 0);
    tmr_output_channel_buffer_enable(TMR8, TMR_SELECT_CHANNEL_1, TRUE);

    tmr_output_channel_config(TMR8, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR8, TMR_SELECT_CHANNEL_2, 0);
    tmr_output_channel_buffer_enable(TMR8, TMR_SELECT_CHANNEL_2, TRUE);

    tmr_output_channel_config(TMR8, TMR_SELECT_CHANNEL_3, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR8, TMR_SELECT_CHANNEL_3, 0);
    tmr_output_channel_buffer_enable(TMR8, TMR_SELECT_CHANNEL_3, TRUE);

    tmr_output_channel_config(TMR8, TMR_SELECT_CHANNEL_4, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR8, TMR_SELECT_CHANNEL_4, 0);
    tmr_output_channel_buffer_enable(TMR8, TMR_SELECT_CHANNEL_4, TRUE);

    tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_1, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_1, 0);
    tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_1, TRUE);

    tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_2, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_2, 0);
    tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_2, TRUE);

    tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_3, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_3, 0);
    tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_3, TRUE);

    tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_4, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_4, 0);
    tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_4, TRUE);

    tmr_period_buffer_enable(TMR3, TRUE);
    tmr_period_buffer_enable(TMR8, TRUE);

    tmr_channel_buffer_enable(TMR8, TRUE);

    tmr_channel_enable(TMR8, TMR_SELECT_CHANNEL_1, TRUE);
    tmr_channel_enable(TMR8, TMR_SELECT_CHANNEL_2, TRUE);
    tmr_channel_enable(TMR8, TMR_SELECT_CHANNEL_3, TRUE);
    tmr_channel_enable(TMR8, TMR_SELECT_CHANNEL_4, TRUE);

    /* input trigger selection */
    // tmr_trigger_input_select(TMR3, TMR_SUB_INPUT_SEL_IS0);

    /* slave mode selection: hang mode */
    // tmr_sub_mode_select(TMR3, TMR_SUB_HANG_MODE);

    tmr_primary_mode_select(TMR8, TMR_PRIMARY_SEL_OVERFLOW);
    tmr_primary_mode_select(TMR3, TMR_PRIMARY_SEL_OVERFLOW);
    // tmr_sub_sync_mode_set(TMR8, TRUE);

    tmr_output_enable(TMR8, TRUE);
    /* tmr enable counter */
    tmr_counter_enable(TMR3, TRUE);
    tmr_counter_enable(TMR8, TRUE);
}

// 关闭电机
void motor_off(void)
{
    // 禁用定时器8的输出
    tmr_output_enable(TMR8, FALSE);
    // 禁用定时器8的计数器
    // tmr_counter_enable(TMR8, FALSE);
}
void motor_on(void)
{
    tmr_output_enable(TMR8, TRUE);
    tmr_counter_enable(TMR8, TRUE);
}
void led_set_brightness1(uint8_t brightness)
{
    TMR3->c1dt = brightness * 1000 / 255;
}
void led_set_brightness2(uint8_t brightness)
{
    TMR3->c2dt = brightness * 1000 / 255;
}

void led_set_brightness3(uint8_t brightness)
{
    TMR3->c3dt = brightness * 1000 / 255;
}

void led_set_brightness4(uint8_t brightness)
{
    TMR3->c4dt = brightness * 1000 / 255;
}
/**
 * @brief set motor frequency
 *
 * @param freq 1~100K
 */
void motor_set_freq(uint32_t freq)
{
    static uint32_t last_freq = 0;
    if (freq)
    {
        if(last_freq != freq)
        {
            last_freq = freq;
            freq = freq > 100000 ? 100000 : freq;
            uint32_t div = 100 * 1000 / freq - 1;
            tmr_base_init(TMR8, 1000, div);
        }
    }
    else
    {
        if(last_freq != freq)
        {
            last_freq = freq;
            tmr_base_init(TMR8, 1000, 9);
        }
    }
}
/**
 * @brief set motor duty
 *
 * @param channel 0~3
 * @param duty 0~1000
 */
void motor_set_duty(uint8_t channel, uint16_t duty)
{
    if(duty > 999) duty = 999;
    switch (channel)
    {
    case 0:
        TMR8->c1dt = duty;
        motor_values[0] = duty;
        break;
    case 1:
        TMR8->c2dt = duty;
        motor_values[1] = duty;
        break;
    case 2:
        TMR8->c3dt =  duty;
        motor_values[2] = duty;
        break;
    case 3:
        TMR8->c4dt =  duty;
        motor_values[3] = duty;
        break;

    default:
        break;
    }
}
void motors_set(uint16_t duty1, uint16_t duty2, uint16_t duty3, uint16_t duty4)
{
    TMR8->c1dt = duty1 > 999 ? 999 : duty1;
    TMR8->c2dt = duty2 > 999 ? 999 : duty2;
    TMR8->c3dt = duty3 > 999 ? 999 : duty3;
    TMR8->c4dt = duty4 > 999 ? 999 : duty4;

    motor_values[0] = TMR8->c1dt;
    motor_values[1] = TMR8->c2dt;
    motor_values[2] = TMR8->c3dt;
    motor_values[3] = TMR8->c4dt;
}
/**
 * @}
 */

/**
 * @}
 */
